home *** CD-ROM | disk | FTP | other *** search
- _ENHANCING THE ACTOR DEVELOPMENT ENVIRONMENT_
- by Steve Hatchett
-
- [LISTING ONE]
-
-
- /* EXTEND.LOD - Actor development extensions load file
- * Copyright(C) 1991 Steve Hatchett. All rights reserved.
- * Steve Hatchett 14352 Mussey Grade Rd.
- * CIS: 70304,1423 Ramona, CA 92065
- * Use this file to load the development environment
- * extensions for use with the Actor programming
- * language.
- * load("extend.lod");
- * load();
- */
- #define MAXSOURCENEST 5; /* max directory nesting */
- Actor[#Programmer] := " "; /* set this in workspace */
- Actor[#StampText] := "Stamp";/* time stamp header. Another
- * useful stamp header would be
- * "Copyright (C) 1991 XYZ, Inc."*/
- LoadFiles :=
- {
- /* Your path may be different. */
- load(new(SourceFile),"c:\actor\general\classes\string.clx");
- load(#("classes\extsource.cls"
- "c:\actor\general\classes\symbol.clx"));
-
- /* The minimum code necessary to navigate the directory
- * hierarchy has now been loaded, paths are no longer needed. */
- do(#(Behavior Browser ClassDialog ClVarDialog Function
- SourceFile System ToolWind WorkEdit), {using(cl)
- loadExtensions(cl);
- });
- }!!
-
-
- [LISTING TWO]
-
- /* EXTSOURCE.CLS - Actor development extensions
- Copyright (C) 1991 Steve Hatchett. All rights reserved.
- Provides access to class source code. Allows the source code for a class
- to be contained in more than one file ordered hierarchically by directory
- structure. There is one .cls file containing the actual class definition.
- Additional .clx files may be exist at lower levels of the hierarchy. They
- can contain methods and class initialization code. */!!
-
- inherit(Object, #ExtSourceFiler,
- #(clName /* Name of class being handled. */
- ownsClass /* True if the .cls file for class is
- in this session's directory. */
- fileNames /* Source code file names with paths. */
- ownsLast /* True if we owned the last method
- we read. */), 2, nil)!!
-
- now(class(ExtSourceFiler))!!
-
- /* Return a new ExtSourceFiler, initialized to handle source code for the
- class whose name Symbol was given. */
- Def openClass(self className)
- {
- ^init(new(self),className);
- } !!
-
- now(ExtSourceFiler)!!
-
- /* Load class extension files (.clx) for the class, but don't load the class
- file (.cls). This is useful for loading extensions to the standard
- Actor classes. Looks for all files in CLASSES subdirectories. */
- Def loadExtensions(self | work fNames fnm)
- {
- work := loadString(332);
- if size(fileNames) > 0
- cand subString(first(fileNames),0,size(work))=work
- fileNames[0] := loadString(331) + getFileName(self);
- if not(exists(File,fileNames[0],0))
- removeFirst(fileNames);
- endif;
- endif;
- if size(fileNames) > 0
- fNames := copy(fileNames);
- fnm := last(fNames);
- if fnm[size(fnm)-1] == 's'
- pop(fNames); /* removes the .cls file */
- endif;
- ^do(reverse(fNames), {using(fnm)
- load(new(SourceFile),fnm);
- });
- endif;
- ^nil;
- }!!
-
- /* Recompile the class by loading all its source code.
- Looks in WORK for own source file if class is dirty. */
- Def recompile(self)
- {
- ^do(reverse(fileNames), {using(fnm)
- load(new(SourceFile),fnm);
- });
- }!!
-
- /* Return open SourceFile with given file name (which should include path). */
- Def openSourceFile(self fName | sFile)
- {
- sFile := new(SourceFile);
- setName(sFile,fName);
- if not(open(sFile,0))
- errorBox(loadString(311), clName
- + loadString(312)+fName+".");
- ^nil;
- endif;
- ^sFile;
- }!!
-
- /* If no source file exists for the class at the directory level of this actor
- session, then create an extension file in WORK, and mark class as dirty. */
- Def mustHaveOwn(self | sFile)
- {
- if size(fileNames) == 0
- cor first(fileNames)[0] == '.'
- add(DirtyClasses,clName);
- insert(fileNames,loadString(332)
- +subString(clName,0,8)+".clx",0);
- makeClassExtFile(new(SourceFile),self);
- endif;
- }!!
-
- /* Replace the the fSym method text with methtext, or add method text if it
- wasn't already in source file. Mode determines whether method is a class or
- object method. These changes will only be made in the source file owned by
- this actor session. Returns nil if not successful. */
- Def saveMethText(self methtext fSym mode | rFile wFile)
- {
- mustHaveOwn(self);
- if (rFile := openClass(SourceFile,self))
- wFile := saveMethText(rFile,methtext,fSym,mode);
- reName(wFile,(fileNames[0] := condDelCFile(rFile,self)));
- endif;
- ^rFile;
- }!!
-
- /* Replace the the class initialization code, with given code. Change will
- only be made in source file owned by this actor session. Returns nil if
- not successful. */
- Def replaceClassInit(self text | rFile wFile)
- {
- mustHaveOwn(self);
- if (rFile := openClass(SourceFile,self))
- wFile := replaceClassInit(rFile,text);
- reName(wFile,(fileNames[0] := condDelCFile(rFile,self)));
- close(rFile);
- endif;
- ^rFile;
- }!!
-
- /* Return the class init code for this class as a TextCollection. */
- Def readClassInit(self | rFile text)
- {
- /* look through source files until some class initialization text is found. */
- ownsLast := false;
- do(fileNames,{using(fnm)
- if (rFile := openSourceFile(self,fnm))
- text := readClassInit(rFile);
- close(rFile);
- if size(text) > 0
- ownsLast := (fnm[0] <> '.');
- ^text;
- endif;
- endif;
- });
- ^new(TextCollection,5);
- }!!
-
- /* Remove the fSym method text if it is found in source file owned by this
- actor session. Mode determines whether method is a class or object method.
- Returns nil if not successful or if method was not in owned source file. */
- Def removeMethod(self fSym mode | rFile wFile)
- {
- if size(fileNames) > 0
- cand first(fileNames)[0] <> '.'
- cand (rFile := openClass(SourceFile,self))
- if wFile := replaceMethod(rFile,nil,fSym,mode)
- reName(wFile,(fileNames[0] := condDelCFile(rFile,self)));
- endif;
- close(rFile);
- endif;
- ^wFile;
- }!!
-
- /* Load the class by loading all its source code. Looks in CLASSES for
- all source files. */
- Def load(self | work)
- {
- work := loadString(332);
- if size(fileNames) > 0
- cand subString(first(fileNames),0,size(work))=work
- fileNames[0] := loadString(331) + getFileName(self);
- if not(exists(File,fileNames[0],0))
- removeFirst(fileNames);
- endif;
- endif;
- ^do(reverse(fileNames), {using(fnm)
- load(new(SourceFile),fnm);
- });
- }
- !!
-
- /* Return true if the last method read using loadMethText was from a source
- file at directory level of this actor session. */
- Def ownsLast(self)
- {
- ^ownsLast;
- }!!
-
- /* Initialize a new ExtSourceFiler. */
- Def init(self nm | metaNm)
- {
- if class(nm) <> Symbol
- nm := name(nm);
- endif;
- if (metaNm := isMetaName(nm))
- clName := name(value(metaNm));
- else
- clName := nm;
- endif;
- getFileNames(self);
- }!!
-
- /* Return true if the .cls file for the class this filer is handling exists
- at the directory level of this actor session. */
- Def ownsClass(self)
- {
- ^ownsClass;
- }!!
-
- /* Return text of aMethod. Note accordingly if source code is missing. Mode
- indicates type of method, either class (BR_CMETH) or object (BR_OMETH). Looks
- through all the source files for the class. */
- Def loadMethText(self aMethod mode | text rFile)
- {
- /* look through source files until the text for the given method is found. */
- ownsLast := false;
- rFile := new(SourceFile);
- do(fileNames,{using(fnm)
- if not(rFile := openSourceFile(self,fnm))
- errorBox(loadString(311), clName
- +loadString(312)+fnm+".");
- else
- text := findMethod(rFile,aMethod,mode);
- close(rFile);
- if text
- ownsLast := (fnm[0] <> '.');
- ^leftJustify(text[0]);
- endif;
- endif;
- });
- ^aMethod + loadString(310);
- }!!
-
- /* Return the class's name the way Behavior would do it. */
- Def name(self)
- {
- ^clName;
- }!!
-
- /* Return the class's filename the way Behavior would do it. */
- Def getFileName(self | dir)
- {
- /* return name + ext */
- ^subString(clName,0,8)
- + if ownsClass
- ".cls" else ".clx" endif;
- }!!
-
- /* Get the names of the files containing this class' source code. */
- Def getFileNames(self | dir fRoot base)
- {
- fileNames := new(OrderedCollection,MAXSOURCENEST);
- dir := loadString(if clName in DirtyClasses
- 332 else 331 endif);
- base := subString(clName,0,8);
- fRoot := dir + base;
- do(MAXSOURCENEST, {using(i | fnm)
-
- /* if the original .cls file or a .clx file is found for class, add it to list
- if it's above this session's directory. */
- if exists(File,(fnm:=fRoot+".cls"),0)
- add(fileNames,fnm);
- if i==0
- ownsClass := true;
- endif;
- ^fileNames;
- endif;
- if exists(File,(fnm:=fRoot+".clx"),0)
- add(fileNames,fnm);
- endif;
-
- /* construct the path name of the next higher level. */
- if i==0
- fRoot := "..\classes\"+base;
- else
- fRoot := "..\"+fRoot;
- endif;
- });
- ^fileNames;
- }!!
-
- /* Return the names of the files containing this class' source code
- (including own source file). */
- Def fileNames(self)
- {
- ^fileNames;
- }!!
-
-
- [LISTING THREE]
-
- /* TOOLWIND.CLX - Actor development extensions
- *
- * Copyright(C) 1991 Steve Hatchett. All rights reserved.
- */!!
- now(class(ToolWindow))!!
-
- /* Used by the system to initialize the DirtyClasses
- Set backup file. DirtyClasses is assumed to be
- empty on entry. For each class found in the backup
- file, ask the user whether to re-load the dirty
- class file or use the old class file.
-
- swh modified to support extended source files.
- swh modified to support unique dirty class file
- names between images.
- */
- Def loadDirty(self | dName)
- {
- /* mod for unique dirty file name - base the dirty
- * file name on the image name.
- */
- setName($DFile,subString(imageName(TheApp),0,
- indexOf(imageName(TheApp),'.',0))
- +".drt");
- /* end mod */
-
- if open($DFile, 0)
- then
- ...
- if size(DirtyClasses) > 0
- then do(copy(DirtyClasses),
- {using(clName)
-
- /* mod for extended source file support - if the dirty
- * class exists in the system, let it tell us its file
- * name (.cls or .clx), otherwise the class was created
- * since the last snapshot, so it should be a .cls file.
- */
- dName := loadString(332) + subString(clName,0,8)
- + if not(Classes[clName])
- cor isOwnClass(Classes[clName])
- ".cls" else ".clx" endif;
- /* end mod */
-
- dName := loadString(332) + subString(clName,0,8) + ".cls";
- ...
- }!!
-
- now(ToolWindow)!!
-
- /* Insert/overwrite a time stamp as the first line of
- the method text.
- */
- Def stampMethText(self text fSym mode | stampHead)
- {
- stampHead := "/*"+StampText;
-
- /* if method doesn't already have a stamp, insert
- * a line for it.
- */
- if left(text[0],size(stampHead),' ') <> stampHead
- insert(text,"",0);
- endif;
-
- /* construct the time stamp. */
- text[0] := stampHead+" "+timeStamp(System)+" "
- +programmer(System)+" "+name(selClass)
- +if mode == BR_CMETH
- "(Class)" else "" endif
- +":"+fSym+" */";
- }!!
-
- /* Save the new text for current method into the source
- file. The first argument, text, is the method text. The
- second, fSym, is the symbol with the name of the method,
- e.g. #print. The new or revised method text ends up in a
- class source file in WORK. Also, write the text to the
- change log.
-
- swh modified to support extended source files
- swh modified to support automatic time stamping
- */
- Def saveMethText(self, text, fSym | textEnd, nowCl, rFile, wFile)
- {...
- changeLog(ew, "now(" + nowCl + ")" + Chunk +
- subText(text, 0, 0, textEnd, size(text[textEnd])));
-
- /* mod for automatic time stamps
- * place time stamp in method text.
- */
- if text
- stampMethText(self,text,fSym,mode);
- endif;
- /* end mod */
-
- /* mod to support extended source files */
- saveMethText(openClass(ExtSourceFiler,selClass),
- text, fSym, mode);
- /* end mod */
-
- makeDirty(self);
- endif;
- ^fSym;
- }!!
-
- /* ToolWindow class initialization
- Rewritten to override ToolWindow.cls class
- initialization to support unique dirty file
- names between images - base the dirty file
- name on the image name.
- */
- $DFile := setName(new(TextFile),
- subString(imageName(TheApp),0,
- indexOf(imageName(TheApp),'.',0))
- +".drt");
-
-
-
-
-
-